package com.platform.qujia.utils.sxfpay;

/*
 * <Title> SXFPayUtil </Title>
 * <Description>随行付第三方支付聚合接口 </Description>
 * @Date：2021年10月28日
 * @Author： JK
 */

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import com.platform.qujia.utils.HttpUtils;
import com.platform.qujia.utils.RSASignature;
import com.platform.qujia.utils.ResultData;
import com.platform.qujia.utils.SXFPaySign;
import com.platform.qujia.utils.exception.EndingException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.LinkedHashMap;

public class SXFPayUtil {

    private static Logger logger =(Logger) LoggerFactory.getLogger(SXFPayUtil.class);

    //private  static String URL = "https://openapi-test.tianquetech.com/order/jsapiScan";                      //测试地址
    private  static String URL = "https://openapi.suixingpay.com/order/jsapiScan";              //生产地址


    /*
     * 随行付第三方聚合支付调用
     * @param sxfPayParam
     * @return
     */
    public static HashMap<String, Object> tradeJsApiScan(SXFPayParam sxfPayParam){
        HashMap<String, Object> resultInfo = new HashMap<>();
        try {
            logger.info("随行付调用传递参数信息：" + sxfPayParam.toString());
            JSONObject reqData = new JSONObject();              //将业务参数存放在 JSON 对象中
            reqData.put("ordNo", sxfPayParam.getOrdNo());       //订单号
            reqData.put("amt", sxfPayParam.getAmt());           //订单总金额
            reqData.put("mno", sxfPayParam.getMno());           //商户编号
            reqData.put("subject", sxfPayParam.getSubject());   //订单标题
            reqData.put("tradeSource", "01");                   //交易来源 01服务商，02收银台，03硬件
            reqData.put("trmIp", "172.16.2.1");                 //商家ip地址
            reqData.put("notifyUrl", sxfPayParam.getNotifyUrl());       //回调地址

            //根据用户类型 和 微信支付来源赋予不同的参数；
            switch (sxfPayParam.getUserType()){
                case "1":   //微信
                    reqData.put("userId", sxfPayParam.getUserId());     //用户号 微信：openid； 支付宝：userid；银联：userid；微信&支付宝必传，银联js为非必传
                    reqData.put("subAppid", sxfPayParam.getAppId());    //AppID
                    reqData.put("payType", "WECHAT");           // 支付渠道 WECHAT：微信；ALIPAY:支付宝；UNIONPAY:银联
                    if("1".equals(sxfPayParam.getWeChatType())){
                        reqData.put("payWay", "03");            // 02 微信公众号/支付宝服务窗/银联js支付/支付宝小程序；03 微信小程序；
                    }
                    if("2".equals(sxfPayParam.getWeChatType())){
                        reqData.put("payWay", "02");
                    }
                    break;
                case "2":   //支付宝
                    reqData.put("userId", sxfPayParam.getUserId());     //用户号 微信：openid； 支付宝：userid；银联：userid；微信&支付宝必传，银联js为非必传
                    reqData.put("payType", "ALIPAY");
                    reqData.put("payWay", "02");
                    //reqData.put("hbFqNum", "6");          //花呗分期数,仅可上送 6 或 12
                    break;
                case "3":   //银联
                    reqData.put("payType", "UNIONPAY");
                    reqData.put("payWay", "02");
                    reqData.put("ylTrmNo", sxfPayParam.getYlTrmNo()); //银联终端号
                    reqData.put("customerIp", sxfPayParam.getCustomerIp()); //持卡人ip地址，银联js支付时必传
                    break;
            }
            reqData.put("outFrontFailUrl", ""); //js 支付，前台 事变通知地址
//        reqData.put("outFrontUrl", ""); //js 支付，前台 成功通知地址
//        reqData.put("timeExpire", "10"); //订单失效时间, 以分钟为单位
//        reqData.put("limitPay", "00"); //限制卡类型: 00-全部 01-限定不能使 用信用卡支付 默认值 00
//        reqData.put("subMechId", ""); //子商户号
//        reqData.put("discountAmt", ""); //参与优惠金额
//        reqData.put("unDiscountAmt", ""); //不参与优惠金额
//        reqData.put("needReceipt", "00"); //电子发票功能 微信开具电子 发票使用
            if(sxfPayParam.getLedgerAccountFlag().equals("1")){
                reqData.put("ledgerAccountFlag", "00"); //是否做分账 分账交易使 用；00：做； 01：不做；不传默认为不做分账
                reqData.put("ledgerAccountEffectTime", "01"); //分账有效时间 单位为天；是 否做分账选择 00 时该字段必传
            }

//        reqData.put("ruleId", "00"); //同 步 分 账 规 则 id
//        reqData.put("fusruleId", "00"); //同步分账规则
//        reqData.put("terminalId", ""); //TQ机具编号
//        reqData.put("deviceNo ", "1111"); //设备号
//        reqData.put("identityFlag", ""); //是否是实名支付
//        reqData.put("buyerIdType", "IDCARD"); //证件类型
//        reqData.put("buyerIdNo", "410523198701054018"); //证件号
//        reqData.put("buyerName", "张三"); //买家姓名
//        reqData.put("mobileNum", ""); //手机号
//        reqData.put("extend", ""); //备用

            String req= SXFPaySign.getSXFPay(reqData);
            logger.info("参数信息："+req);
            //此处不要改变reqData里面值的顺序用LinkedHashMap
            HashMap reqMap = JSON.parseObject(req, LinkedHashMap.class, Feature.OrderedField);
            //组装加密串
            String signContent = RSASignature.getOrderContent(reqMap);
            //logger.info("拼接后的参数："+signContent);
            //sign
            String sign = RSASignature.encryptBASE64(RSASignature.sign(signContent, SXFPaySign.privateKey));
            //logger.info("本次签名信息:" + sign);
            reqMap.put("sign", sign);
            //System.out.println("放入sign后请求参数:" + reqMap);
            String reqStr = JSON.toJSONString(reqMap);
            //logger.info("reqStr Json转String请求参数:" + reqStr);
            //调用第三方接口地址
            String resultJson = HttpUtils.connectPostUrl(URL, reqStr);
            logger.info("随行付返回信息："+resultJson);
            //不要对reqData排序 所以用LinkedHashMap
            HashMap<String, Object> result = JSON.parseObject(resultJson, LinkedHashMap.class, Feature.OrderedField);
            if ("0000".equals(result.get("code"))) {
                //验签
                String signResult = result.get("sign").toString();
                result.remove("sign");
                String resultStr = RSASignature.getOrderContent(result);
                //logger.info("resultStr: " + resultStr);
                //sign
                String resultSign = RSASignature.encryptBASE64(RSASignature.sign(signContent, SXFPaySign.privateKey));
                logger.info("resultSign: " + resultSign);
                //组装加密串
//                if (RSASignature.doCheck(resultStr, signResult, SXFPaySign.sxfPublic)) {
                    System.out.println("===================验签成功==============");
                    logger.info("随行付返回字段：" +result);
                    resultInfo.put("code", result.get("code"));
                    resultInfo.put("msg", result.get("msg"));
                    JSONObject respData = (JSONObject)result.get("respData");
                    resultInfo.put("payTimeStamp", respData.get("payTimeStamp"));
                    resultInfo.put("ordNo", respData.get("ordNo"));
                    resultInfo.put("payPackage", respData.get("payPackage"));
                    resultInfo.put("bizMsg", respData.get("bizMsg"));
                    resultInfo.put("paySign", respData.get("paySign"));
                    resultInfo.put("bizCode", respData.get("bizCode"));
                    resultInfo.put("payAppId", respData.get("payAppId"));
                    resultInfo.put("sxfUuid", respData.get("sxfUuid"));
                    resultInfo.put("paynonceStr", respData.get("paynonceStr"));
                    resultInfo.put("paySignType", respData.get("paySignType"));
                    resultInfo.put("merchantsNumber", respData.get("sxfUuid")); //商户单号（商户）
                    resultInfo.put("source", respData.get("source"));           //支付宝流水号或支付宝支付链接
                    resultInfo.put("redirectUrl",respData.get("redirectUrl"));  //银联重定向跳转地址
                    resultInfo.put("uuid", respData.get("uuid"));
                    resultInfo.put("orgId", result.get("orgId"));
                    resultInfo.put("signType", result.get("signType"));
                    resultInfo.put("reqId", result.get("reqId"));

//                }
            }else {
                resultInfo.put("code", result.get("code"));
                resultInfo.put("msg", result.get("msg"));
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        logger.info("随行付返回前端字段：" + resultInfo.toString());
        return resultInfo;
    }


    /*
     * 随行付第三方聚合支付调用
     * @param sxfPayParam
     * @return
     */
    public static HashMap<String, Object> sxfGoPay(SXFPayParam sxfPayParam) throws Exception {
        logger.info("sxfGoPay-Start-" + "随行付支付-ordNo:" + sxfPayParam.getOrdNo() + "-amt:" + sxfPayParam.getAmt());
        logger.info("sxfGoPay-入参-" + sxfPayParam.toString());

        HashMap<String, Object> resultInfo = new HashMap<>();
        JSONObject reqData = new JSONObject();              //将业务参数存放在 JSON 对象中
        reqData.put("ordNo", sxfPayParam.getOrdNo());       //订单号
        reqData.put("amt", sxfPayParam.getAmt());           //订单总金额
        reqData.put("mno", sxfPayParam.getMno());           //商户编号
        reqData.put("subject", sxfPayParam.getSubject());   //订单标题
        reqData.put("tradeSource", "01");                   //交易来源 01服务商，02收银台，03硬件
        reqData.put("trmIp", "172.16.2.1");                 //商家ip地址
        reqData.put("notifyUrl", sxfPayParam.getNotifyUrl());       //回调地址

        //根据用户类型 和 微信支付来源赋予不同的参数；
        switch (sxfPayParam.getUserType()) {
            case "1":   //微信
                reqData.put("userId", sxfPayParam.getUserId());     //用户号 微信：openid； 支付宝：userid；银联：userid；微信&支付宝必传，银联js为非必传
                reqData.put("subAppid", sxfPayParam.getAppId());    //AppID
                reqData.put("payType", "WECHAT");           // 支付渠道 WECHAT：微信；ALIPAY:支付宝；UNIONPAY:银联
                if ("1".equals(sxfPayParam.getWeChatType())) {
                    reqData.put("payWay", "03");            // 02 微信公众号/支付宝服务窗/银联js支付/支付宝小程序；03 微信小程序；
                }
                if ("2".equals(sxfPayParam.getWeChatType())) {
                    reqData.put("payWay", "02");
                }
                break;
            case "2":   //支付宝
                reqData.put("userId", sxfPayParam.getUserId());     //用户号 微信：openid； 支付宝：userid；银联：userid；微信&支付宝必传，银联js为非必传
                reqData.put("payType", "ALIPAY");
                reqData.put("payWay", "02");
                //reqData.put("hbFqNum", "6");          //花呗分期数,仅可上送 6 或 12
                break;
            case "3":   //银联
                reqData.put("payType", "UNIONPAY");
                reqData.put("payWay", "02");
                reqData.put("ylTrmNo", sxfPayParam.getYlTrmNo()); //银联终端号
                reqData.put("customerIp", sxfPayParam.getCustomerIp()); //持卡人ip地址，银联js支付时必传
                break;
        }
        reqData.put("outFrontFailUrl", ""); //js 支付，前台 事变通知地址
//        reqData.put("outFrontUrl", ""); //js 支付，前台 成功通知地址
//        reqData.put("timeExpire", "10"); //订单失效时间, 以分钟为单位
//        reqData.put("limitPay", "00"); //限制卡类型: 00-全部 01-限定不能使 用信用卡支付 默认值 00
//        reqData.put("subMechId", ""); //子商户号
//        reqData.put("discountAmt", ""); //参与优惠金额
//        reqData.put("unDiscountAmt", ""); //不参与优惠金额
//        reqData.put("needReceipt", "00"); //电子发票功能 微信开具电子 发票使用
        if(sxfPayParam.getLedgerAccountFlag().equals("1")){
        reqData.put("ledgerAccountFlag", "00"); //是否做分账 分账交易使 用；00：做； 01：不做；不传默认为不做分账
        reqData.put("ledgerAccountEffectTime", "01"); //分账有效时间 单位为天；是 否做分账选择 00 时该字段必传
        }

//        reqData.put("ruleId", "00"); //同 步 分 账 规 则 id
//        reqData.put("fusruleId", "00"); //同步分账规则
//        reqData.put("terminalId", ""); //TQ机具编号
//        reqData.put("deviceNo ", "1111"); //设备号
//        reqData.put("identityFlag", ""); //是否是实名支付
//        reqData.put("buyerIdType", "IDCARD"); //证件类型
//        reqData.put("buyerIdNo", "410523198701054018"); //证件号
//        reqData.put("buyerName", "张三"); //买家姓名
//        reqData.put("mobileNum", ""); //手机号
//        reqData.put("extend", ""); //备用

        String req = SXFPaySign.getSXFPay(reqData);
        //此处不要改变reqData里面值的顺序用LinkedHashMap
        HashMap reqMap = JSON.parseObject(req, LinkedHashMap.class, Feature.OrderedField);
        //组装加密串
        String signContent = RSASignature.getOrderContent(reqMap);
        //sign
        String sign = RSASignature.encryptBASE64(RSASignature.sign(signContent, SXFPaySign.privateKey));
        reqMap.put("sign", sign);
        String reqStr = JSON.toJSONString(reqMap);
        logger.info("sxfGoPay-随行付请求参数-" + reqStr);
        //调用第三方接口地址
        String resultJson = HttpUtils.connectPostUrl(URL, reqStr);
        logger.info("sxfGoPay-随行付返回参数-" + resultJson);
        //不要对reqData排序 所以用LinkedHashMap
        HashMap<String, Object> result = JSON.parseObject(resultJson, LinkedHashMap.class, Feature.OrderedField);

        if (!"0000".equals(result.get("code"))) {
            throw new EndingException((String) result.get("msg"));
        }

        //验签
        String signResult = result.get("sign").toString();
        result.remove("sign");
        String resultStr = RSASignature.getOrderContent(result);

        //String resultSign = RSASignature.encryptBASE64(RSASignature.sign(signContent, SXFPaySign.privateKey));
        //组装加密串
//        if (!RSASignature.doCheck(resultStr, signResult, SXFPaySign.sxfPublic)) {
//            throw new EndingException("验签不通过");
//        }


        resultInfo.put("code", result.get("code"));
        resultInfo.put("msg", result.get("msg"));
        JSONObject respData = (JSONObject) result.get("respData");
        resultInfo.put("payTimeStamp", respData.get("payTimeStamp"));
        resultInfo.put("ordNo", respData.get("ordNo"));
        resultInfo.put("payPackage", respData.get("payPackage"));
        resultInfo.put("bizMsg", respData.get("bizMsg"));
        resultInfo.put("paySign", respData.get("paySign"));
        resultInfo.put("bizCode", respData.get("bizCode"));
        resultInfo.put("payAppId", respData.get("payAppId"));
        resultInfo.put("sxfUuid", respData.get("sxfUuid"));
        resultInfo.put("paynonceStr", respData.get("paynonceStr"));
        resultInfo.put("paySignType", respData.get("paySignType"));
        resultInfo.put("merchantsNumber", respData.get("sxfUuid")); //商户单号（商户）
        resultInfo.put("source", respData.get("source"));           //支付宝流水号或支付宝支付链接
        resultInfo.put("redirectUrl", respData.get("redirectUrl"));  //银联重定向跳转地址
        resultInfo.put("uuid", respData.get("uuid"));
        resultInfo.put("orgId", result.get("orgId"));
        resultInfo.put("signType", result.get("signType"));
        resultInfo.put("reqId", result.get("reqId"));

        logger.info("sxfGoPay-End-出参:" + resultInfo.toString());

        return resultInfo;
    }
}
